package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.domain.DrugType;
import com.yixin.hospital.entity.domain.JobOffice;
import com.yixin.hospital.entity.domain.VisitTemplate;
import com.yixin.hospital.entity.domain.VisitTemplateJobOffice;
import com.yixin.hospital.entity.dto.req.visitTemplate.VisitTemplateEditTemplateReqDTO;
import com.yixin.hospital.entity.dto.req.visitTemplate.VisitTemplateJobOfficeReqDTO;
import com.yixin.hospital.entity.vo.DrugTypeVO;
import com.yixin.hospital.entity.vo.VisitInfoVO;
import com.yixin.hospital.entity.vo.VisitTemplateJobOfficeVO;
import com.yixin.hospital.service.JobOfficeService;
import com.yixin.hospital.service.VisitTemplateJobOfficeService;
import com.yixin.hospital.service.VisitTemplateService;
import com.yixin.hospital.utils.JwtUtil;
import com.yixin.hospital.utils.SqeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static com.yixin.hospital.enums.ResponseCodeEnum.JOB_OFFICE_VISIT_TEMPLATE_EXIT;
import static com.yixin.hospital.enums.ResponseCodeEnum.JOB_OFFICE_VISIT_TEMPLATE_NOT_FOUND;

@RestController
@RequestMapping("/visit-template-job-office")
@Api(value = "就诊模板管理", tags = "就诊模板管理")
public class VisitTemplateJobOfficeController {

    @Resource
    VisitTemplateService visitTemplateService;

    @Resource
    VisitTemplateJobOfficeService visitTemplateJobOfficeService;

    public static String generateTransactionID() {
        String random = RandomStringUtils.randomAlphabetic(9).toUpperCase();
        String mili = String.valueOf(System.currentTimeMillis());
        String subMili = mili.substring(mili.length() - 6, mili.length());
        return StringUtils.join(random, subMili);
    }

    public static void main(String[] args) {
        String a = String.valueOf(1790673095405604864l);
        System.out.println(SqeUtil.getRandomByLength(6) +a.substring(a.length()-10));
    }

    @Resource
    JobOfficeService jobOfficeService;

    @GetMapping("/info")
    @ApiOperation(value = "科室就诊模板详情")
    public ApiResult info(int jobOfficeId) {
        List<VisitTemplateJobOffice> templateCodeList = visitTemplateJobOfficeService.list(new LambdaQueryWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, jobOfficeId));
        if (CollectionUtil.isEmpty(templateCodeList)) return ApiResult.error(JOB_OFFICE_VISIT_TEMPLATE_NOT_FOUND);
        List<String> codeList = templateCodeList.stream().map(VisitTemplateJobOffice::getTemplateCode).collect(Collectors.toList());
        List<VisitTemplate> templateList = visitTemplateService.list(new LambdaQueryWrapper<VisitTemplate>().in(VisitTemplate::getTemplateCode, codeList));
        TreeNodeConfig nodeConfig = new TreeNodeConfig();
        List<Tree<Integer>> treeList = TreeUtil.build(templateList, 0, nodeConfig,
                (node, tree) -> {
                    tree.setId(node.getId().intValue());
                    tree.setParentId(node.getPid().intValue());
                    tree.setName(node.getName());
                    tree.putExtra("level", node.getLevel());
                    tree.putExtra("templateCode", node.getTemplateCode());
                    tree.putExtra("templateName", node.getTemplateName());
                    tree.putExtra("level", node.getLevel());
                    tree.putExtra("sort", node.getSort());
                    tree.putExtra("value", "");
                    tree.putExtra("isFocus", false);
                });

        if (CollectionUtil.isEmpty(treeList)) return ApiResult.success(new ArrayList<>());
        for (Tree<Integer> integerTree : treeList) {
            getChildren(integerTree);
        }
        treeList.sort(Comparator.comparing((Tree o) -> (String) o.get("templateCode")).thenComparing((Tree o) -> Integer.valueOf((Integer) o.get("sort"))));
        return ApiResult.success(treeList);
    }

    private List<Tree<Integer>> getChildren(Tree<Integer> integerTree) {
        if (!CollectionUtil.isEmpty(integerTree.getChildren())) {
            integerTree.getChildren().sort(Comparator.comparing((Tree o) -> (String) o.get("templateCode")).thenComparing((Tree o) -> Integer.valueOf((Integer) o.get("sort"))));
            for (Tree<Integer> child : integerTree.getChildren()) {
                getChildren(child);
            }
        }
        return null;
    }


//    @GetMapping("/info")
//    @ApiOperation(value = "科室就诊模板详情")
//    public ApiResult info(int jobOfficeId) {
//        List<VisitTemplateJobOffice> templateCodeList = visitTemplateJobOfficeService.list(new LambdaQueryWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, jobOfficeId));
//        if (CollectionUtil.isEmpty(templateCodeList)) return ApiResult.error(JOB_OFFICE_VISIT_TEMPLATE_NOT_FOUND);
//        Set<String> codeList = templateCodeList.stream().map(VisitTemplateJobOffice::getTemplateCode).collect(Collectors.toSet());
//        List<VisitTemplate> templateList = visitTemplateService.list(new LambdaQueryWrapper<VisitTemplate>().in(VisitTemplate::getTemplateCode, codeList));
//        TreeNodeConfig nodeConfig = new TreeNodeConfig();
//        List<Tree<Integer>> treeList = TreeUtil.build(templateList, 0, nodeConfig,
//                (node, tree) -> {
//                    tree.setId(node.getId().intValue());
//                    tree.setParentId(node.getPid().intValue());
//                    tree.setName(node.getName());
//                    tree.putExtra("templateCode", node.getTemplateCode());
//                    tree.putExtra("templateName", node.getTemplateName());
//                    tree.putExtra("level", node.getLevel());
//                    tree.putExtra("sort", node.getSort());
//                    tree.putExtra("value", "");
//                    tree.putExtra("isFocus", false);
//                });
//        Map<String, VisitInfoVO> codeMap = new HashMap<>();
//        for (Tree<Integer> integerTree : treeList) {
//            String code = String.valueOf(integerTree.get("templateCode"));
//            VisitInfoVO templateCode = codeMap.get(code);
//            if (Objects.isNull(templateCode)) {
//                templateCode = new VisitInfoVO();
//                templateCode.getVisitTemplateList().add(integerTree);
//                codeMap.put(code, templateCode);
//                continue;
//            }
//            templateCode.getVisitTemplateList().add(integerTree);
//        }
//        List<VisitInfoVO> visitInfoVOList = codeMap.keySet().stream().map(code -> {
//            VisitInfoVO visitInfoVO = codeMap.get(code);
//            visitInfoVO.setTemplateCode(String.valueOf(visitInfoVO.getVisitTemplateList().get(0).get("templateCode")));
//            visitInfoVO.setTemplateName(String.valueOf(visitInfoVO.getVisitTemplateList().get(0).get("templateName")));
//            return visitInfoVO;
//        }).collect(Collectors.toList());
//        return ApiResult.success(visitInfoVOList);
//    }

    @GetMapping("/list")
    @ApiOperation(value = "科室就诊模板列表")
    public ApiResult list() {
        List<VisitTemplateJobOffice> list = visitTemplateJobOfficeService.list(new LambdaUpdateWrapper<VisitTemplateJobOffice>().orderByDesc(VisitTemplateJobOffice::getCreatedTime));
        List<VisitTemplateJobOfficeVO> responseList = new ArrayList<>();
        Map<Long, VisitTemplateJobOfficeVO> responseMap = new HashMap<>();
        for (VisitTemplateJobOffice visitTemplateJobOffice : list) {
            VisitTemplateJobOfficeVO visitTemplateJobOfficeVO = responseMap.get(visitTemplateJobOffice.getJobOfficeId());
            if (Objects.isNull(visitTemplateJobOfficeVO)) {
                visitTemplateJobOfficeVO = new VisitTemplateJobOfficeVO();
                visitTemplateJobOfficeVO.setJobOfficeId(visitTemplateJobOffice.getJobOfficeId());
                responseMap.put(visitTemplateJobOfficeVO.getJobOfficeId(), visitTemplateJobOfficeVO);
                responseList.add(visitTemplateJobOfficeVO);
            }
            JobOffice jobOffice = jobOfficeService.getById(visitTemplateJobOffice.getJobOfficeId());
            if (Objects.nonNull(jobOffice)) visitTemplateJobOfficeVO.setJobOfficeName(jobOffice.getName());
            List<VisitTemplate> visitTemplateList = visitTemplateService.list(new LambdaUpdateWrapper<VisitTemplate>().eq(VisitTemplate::getTemplateCode, visitTemplateJobOffice.getTemplateCode()));
            if (!CollectionUtil.isEmpty(visitTemplateList))
                visitTemplateJobOfficeVO.getVisitTemplateList().add(new VisitTemplateEditTemplateReqDTO(visitTemplateList.get(0).getTemplateCode(), visitTemplateList.get(0).getTemplateName()));

        }
        return ApiResult.success(responseList);
    }

    @PostMapping("/add")
    @ApiOperation(value = "新增就诊管理类别")
    public ApiResult add(@Valid @RequestBody VisitTemplateJobOfficeReqDTO visitTemplateAddReqDTO, HttpServletRequest request) {
        List<VisitTemplateJobOffice> jobOfficeExist = visitTemplateJobOfficeService.list(new LambdaUpdateWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, visitTemplateAddReqDTO.getJobOfficeId()));
        if (!CollectionUtil.isEmpty(jobOfficeExist)) return ApiResult.error(JOB_OFFICE_VISIT_TEMPLATE_EXIT);
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        List<VisitTemplateJobOffice> list = new ArrayList<>();
        for (String visitTemplateCode : visitTemplateAddReqDTO.getVisitTemplateCodeList()) {
            VisitTemplateJobOffice visitTemplateJobOffice = new VisitTemplateJobOffice();
            visitTemplateJobOffice.setJobOfficeId(visitTemplateAddReqDTO.getJobOfficeId());
            visitTemplateJobOffice.setTemplateCode(visitTemplateCode);
            visitTemplateJobOffice.setCreatedBy(userName);
            visitTemplateJobOffice.setUpdatedBy(userName);
            list.add(visitTemplateJobOffice);
        }
        visitTemplateJobOfficeService.saveBatch(list);
        return ApiResult.success();
    }

    @PutMapping("/edit")
    @ApiOperation(value = "修改就诊管理类别")
    @Transactional
    public ApiResult edit(@Valid @RequestBody VisitTemplateJobOfficeReqDTO visitTemplateAddReqDTO, HttpServletRequest request) {
        visitTemplateJobOfficeService.remove(new LambdaUpdateWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, visitTemplateAddReqDTO.getJobOfficeId()));
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        List<VisitTemplateJobOffice> list = new ArrayList<>();
        for (String visitTemplateCode : visitTemplateAddReqDTO.getVisitTemplateCodeList()) {
            VisitTemplateJobOffice visitTemplateJobOffice = new VisitTemplateJobOffice();
            visitTemplateJobOffice.setJobOfficeId(visitTemplateAddReqDTO.getJobOfficeId());
            visitTemplateJobOffice.setTemplateCode(visitTemplateCode);
            visitTemplateJobOffice.setCreatedBy(userName);
            visitTemplateJobOffice.setUpdatedBy(userName);
            list.add(visitTemplateJobOffice);
        }
        visitTemplateJobOfficeService.saveBatch(list);
        return ApiResult.success();
    }

    @DeleteMapping("/remove/{jobOfficeId}")
    @ApiOperation(value = "删除就诊管理类别")
    public ApiResult remove(@PathVariable int jobOfficeId) {
        visitTemplateJobOfficeService.remove(new LambdaUpdateWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, jobOfficeId));
        return ApiResult.success();
    }

}
